import time
from collections import OrderedDict

from django.conf import settings
from django.contrib import messages
from django.db.models import Count, Q
from django.http import JsonResponse
from django.shortcuts import render, redirect, reverse

from web import models
from web.utils.link import filter_reverse
from web.utils.pager import Pagernation
from web.utils.blackip import BlackIp

from django_redis import get_redis_connection


def attackip_list(request, pk):
    keyword = request.GET.get("keyword", "").strip()
    con = Q()
    if keyword:
        con.connector = "OR"
        con.children.append(('src_ip__contains', keyword))
    obj = models.SangforFw.objects.filter(id=pk).first()
    data_time = obj.create_datetime
    queryset = models.SangforFwAttackLog.objects.filter(con). \
        filter(create_datetime__year=data_time.year,
               create_datetime__month=data_time.month,
               create_datetime__day=data_time.day).values('src_ip', 'src_ip_addr').annotate(
        ct=Count('src_ip')).order_by('-ct')

    for row in queryset:
        association_devie_list = []
        botgate_exists = models.BotgateAttackIp.objects.filter(create_datetime__year=data_time.year,
                                                               create_datetime__month=data_time.month,
                                                               create_datetime__day=data_time.day,
                                                               src_ip=row['src_ip']).exists()
        if botgate_exists:
            association_devie_list.append('BotGate')
        skyeye_exists = models.SkyEyeLog.objects.filter(create_datetime__year=data_time.year,
                                                        create_datetime__month=data_time.month,
                                                        create_datetime__day=data_time.day,
                                                        attack_sip=row['src_ip']).exists()
        if skyeye_exists:
            association_devie_list.append('SkyEye')

        row['association_devie'] = ",".join(association_devie_list)
    pager = Pagernation(request, queryset)
    context = {
        'pager': pager,
        'keyword': keyword,
        'id': obj.id
    }
    return render(request, 'sangfor_attackip_list.html', context)


def block_ip(request, pk, src_ip):
    sangfor_fw_obj = models.SangforFw.objects.filter(id=pk).first()
    date_time = sangfor_fw_obj.create_datetime
    attacklog_obj = models.SangforFwAttackLog.objects.filter(create_datetime__year=date_time.year,
                                                             create_datetime__month=date_time.month,
                                                             create_datetime__day=date_time.day,
                                                             src_ip=src_ip).first()
    if not attacklog_obj:
        messages.add_message(request, settings.MESSAGE_DANGER_TAG, 'IP不存在')
        return redirect(filter_reverse(request, reverse('sangfor_attackip_list', kwargs={'pk': pk})))

    # 将封禁IP写入redis
    block_ip = attacklog_obj.src_ip
    locaton = attacklog_obj.src_ip_addr
    conn = get_redis_connection('default')
    user = request.session.get(settings.MOBILEDJ_SESSION_KEY)['id']
    blackip_obj = BlackIp(block_ip, 'sangfor_fw', settings.MANUAL_BLOCK, settings.BLOCK, user, date_time, locaton)
    conn.lpush(settings.QUEUE_TASK_NAME, str(blackip_obj))
    messages.add_message(request, messages.SUCCESS, '恶意IP：{}在深信服防火墙封禁成功'.format(block_ip))
    time.sleep(1)
    return redirect(filter_reverse(request, reverse('sangfor_attackip_list', kwargs={'pk': pk})))


def statistics_attackip(request):
    pk = request.GET.get('id')
    obj = models.SangforFw.objects.filter(id=pk).first()
    date_time = obj.create_datetime
    queryset = models.SangforFwAttackLog.objects.filter(create_datetime__year=date_time.year,
                                                        create_datetime__month=date_time.month,
                                                        create_datetime__day=date_time.day). \
        values('src_ip').annotate(ct=Count('src_ip')).order_by("-ct")
    all_attackip_dict = OrderedDict()
    for item in queryset:
        all_attackip_dict[item['src_ip']] = {
            'name': item['src_ip'],
            'level': {item[0]: 0 for item in models.SangforFwAttackLog.level_choices}
        }
    attack_log = models.SangforFwAttackLog.objects.filter(create_datetime__year=date_time.year,
                                                          create_datetime__month=date_time.month,
                                                          create_datetime__day=date_time.day)

    for item in attack_log:
        all_attackip_dict[item.src_ip]['level'][item.level] += 1

    categories = [data['name'] for data in all_attackip_dict.values()]

    data_result_dict = OrderedDict()
    for item in models.SangforFwAttackLog.level_choices:
        data_result_dict[item[0]] = {'name': item[1], "data": []}
    for key, text in models.SangforFwAttackLog.level_choices:
        for row in all_attackip_dict.values():
            count = row['level'][key]
            data_result_dict[key]['data'].append(count)
    context = {
        'status': True,
        'data': {
            'categories': categories,
            'series': list(data_result_dict.values())
        }
    }

    return JsonResponse(context)
